package com.swfpeep.resource
{
	import com.swfpeep.data.SWFFileInfo;
	import com.swfpeep.lang.str;
	import com.swfpeep.log;
	import com.swfpeep.utils.ABCToActionScript;
	import com.swfpeep.utils.ReadableMultiname;
	import com.swfwire.decompiler.AsyncSWFReader;
	import com.swfwire.decompiler.SWFByteArray;
	import com.swfwire.decompiler.SWFReadResult;
	import com.swfwire.decompiler.abc.tokens.NamespaceToken;
	import com.swfwire.decompiler.abc.tokens.ScriptInfoToken;
	import com.swfwire.decompiler.abc.tokens.TraitsInfoToken;
	import com.swfwire.decompiler.abc.tokens.traits.TraitSlotToken;
	import com.swfwire.decompiler.data.swf9.tags.DoABCTag;
	import com.swfwire.decompiler.events.AsyncSWFReaderEvent;
	
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.utils.getTimer;
	
	import mx.controls.ProgressBar;

	public class CreateSWFReadResult extends EventDispatcher
	{
		protected var m_loadProgress:ProgressBar;
		protected var m_parse_star:int;
		protected var m_currentState:String;
		protected var m_result:SWFReadResult;
		protected var m_lastResult:SWFReadResult;
		protected var m_tagDumpCache:Array;
		protected var m_tagHexCache:Array;
		protected var m_customNamespaces:Object;
		
		public function CreateSWFReadResult(loadProgress:ProgressBar)
		{
			this.m_loadProgress = loadProgress;
		}
		
		public function process(swfFileInfo:SWFFileInfo):void
		{
			var swfBytes:SWFByteArray = new SWFByteArray(swfFileInfo.bytes);
			var swf:AsyncSWFReader = new AsyncSWFReader();
			
			swf.addEventListener(AsyncSWFReaderEvent.TAG_READ, tagReadHandler);
			swf.addEventListener(AsyncSWFReaderEvent.READ_COMPLETE, readCompleteHandler);
			
			m_loadProgress.setProgress(0, 0);
			m_parse_star = getTimer();
			m_result = swf.read(swfBytes);
			swfFileInfo.readResult = m_result;
			
		}
		
		private function tagReadHandler(ev:AsyncSWFReaderEvent):void
		{
			var current:uint = ev.context.bytes.getBytePosition();
			var max:uint = ev.context.bytes.getLength();
			
			var preInt:int = int(current / max * 100);
			
			m_loadProgress.setProgress(preInt,100);
			m_loadProgress.label = "解析进度:" + preInt + "%";
		}
		
		private function readCompleteHandler(ev:AsyncSWFReaderEvent):void
		{
			log(str("parsing") +' '+m_result.tagMetadata.length+' tags ('+ev.context.bytes.getLength()+' bytes) took '+(getTimer() - m_parse_star)+'ms.');
			doneHandler();
		}
		
		private function doneHandler():void
		{
			m_currentState = 'loaded';
			m_loadProgress.setProgress(1, 1);
			
			var result:SWFReadResult = m_result;
			
			if(result.errors.length > 0)
			{
				log(result.warnings.length+' errors:');
				log(result.errors.join('\n'));
			}
			else
			{
				log('No errors!');
			}
			
			if(result.warnings.length > 0)
			{
				log(result.warnings.length+' warnings:');
				log('\t'+result.warnings.join('\n\t'));
			}
			else
			{
				log('No warnings!');
			}
			
			m_lastResult = result;
			m_tagDumpCache = [];
			m_tagHexCache = [];
			m_customNamespaces = {};
			
			var dp:Array = [];
			
			dp.push({id: -1, displayId: '', name: 'SWFHeader', size: result.tagMetadata[0].start});
			
			/*for(var iterTag:uint = 0; iterTag < result.tagMetadata.length; iterTag++)
			{
				var metadata:Object = result.tagMetadata[iterTag];
				var label:String = metadata.name.substr(metadata.name.indexOf('::') + 2);
				dp.push({name: label, id: iterTag, displayId: iterTag, size: metadata.length});
				
				var abc:DoABCTag = result.swf.tags[iterTag] as DoABCTag;
				if(abc)
				{
					var translator:ABCToActionScript = new ABCToActionScript(abc.abcFile);
					for each(var iterScript:ScriptInfoToken in abc.abcFile.scripts)
					{
						for each(var traitInfo:TraitsInfoToken in iterScript.traits)
						{
							if(traitInfo.kind == TraitsInfoToken.KIND_TRAIT_SLOT || traitInfo.kind == TraitsInfoToken.KIND_TRAIT_CONST)
							{
								var slotInfo2:TraitSlotToken = TraitSlotToken(traitInfo.data);
								if(slotInfo2.vKind == 0x08)
								{
									var ns:NamespaceToken = abc.abcFile.cpool.namespaces[slotInfo2.vIndex];
									if(ns.kind == NamespaceToken.KIND_Namespace)
									{
										var uri:String = abc.abcFile.cpool.strings[ns.name].utf8;
										var r:ReadableMultiname = new ReadableMultiname();
										translator.getReadableMultiname(traitInfo.name, r);
										m_customNamespaces[uri] = translator.multinameTypeToString(r);
									}
								}
							}
						}
					}
				}
			}
			
			detailsPanel.tagList.addEventListener(ListEvent.CHANGE, tagListChangeHandler);
			
			detailsPanel.tagList.dataProvider = dp;
			if(Config.TESTING)
			{
				detailsPanel.tagList.selectedIndex = 10;
				//detailsPanel.tagList.selectedIndex = 13;
				//detailsPanel.tagList.selectedIndex = 149;
				//detailsPanel.tagList.selectedIndex = 249;
			}
			else
			{
				//detailsPanel.tagList.selectedIndex = 0;
			}
			
			//detailsPanel.currentState = 'actionScript';
			//detailsPanel.actionScript.currentState = 'classes';
			
			//updateBottomPanel();
			*/
			
			dispatchEvent(new Event(Event.COMPLETE));
		}
	}
}